/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;

namespace DaveSexton.DocProject.Engine
{
	internal sealed class InternalCreateDocSiteIndexStep : BuildStep<IBuildEngine>
	{
		#region Public Properties
		public override string Name
		{
			get
			{
				return "Generate Index for DocSite";
			}
		}
		#endregion

		#region Private / Protected
		private readonly HelpSystem help;
		private volatile bool canceled;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="InternalCreateDocSiteIndexStep" /> class.
		/// </summary>
		public InternalCreateDocSiteIndexStep(HelpSystem helpSystem, IBuildEngine engine)
			: base(engine)
		{
			if (helpSystem == null)
				throw new ArgumentNullException("helpSystem");

			help = helpSystem;

			RunInBackground = true;
		}
		#endregion

		#region Methods
		protected override void ExecuteInternal(BuildContext context)
		{
			if (canceled)
			{
				// reset private canceled field in case the step is reused
				canceled = false;
				return;
			}

			IEnumerable<HelpItem> index = help.Index;

			string indexFile = Engine.Settings.DocSiteTargetIndexXmlFile;
			string path = Path.GetDirectoryName(indexFile);

			if (!Directory.Exists(path))
				Directory.CreateDirectory(path);

			context.TraceLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, Resources.Text.CreatingDocSiteIndex, indexFile));

			context.Engine.Project.GetItem(indexFile).Checkout();

			using (FileStream stream = new FileStream(indexFile, FileMode.Create, FileAccess.Write))
			{
				WriteDocSiteIndexXmlFile(index, stream);
			}
		}

		protected override void CancelInternal(BuildContext context)
		{
			canceled = true;
		}

		private void WriteDocSiteIndexXmlFile(IEnumerable<HelpItem> index, Stream stream)
		{
			/* Sample: 
			<?xml version="1.0" encoding="utf-8" ?>
			<index>
				<entry name="WindowsApplication1 namespace" file="html/N_WindowsApplication1.htm" />
				<entry name="Form1 class" file="html/T_WindowsApplication1_Form1.htm" />
			</index>
			 */

			XmlWriterSettings writerSettings = new XmlWriterSettings();
			writerSettings.Indent = true;

			using (XmlWriter writer = XmlWriter.Create(stream, writerSettings))
			{
				writer.WriteStartDocument();
				writer.WriteStartElement("index");

				foreach (HelpItem item in index)
				{
					if (canceled)
					{
						// reset private canceled field in case the step is reused
						canceled = false;
						break;
					}

					writer.WriteStartElement("entry");
					writer.WriteAttributeString("name", item.Name);

					if (item.File != null)
						writer.WriteAttributeString("file", item.File);

					writer.WriteEndElement();
				}

				writer.WriteEndElement();
				writer.WriteEndDocument();
			}
		}

		public override string ToString()
		{
			return "Creates the " + Engine.Settings.DocSiteIndexXmlFileName + " file.";
		}
		#endregion
	}
}
